// Copyright 2019 The rhyme_lph Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// a [author] rhyme_lph
// L [email]  rhymelph@gmail.com
// j [github] https://github.com/rhymelph

import 'package:base_plugin/base_plugin.dart';
import 'package:finance_app/generated/l10n.dart';
import 'package:finance_app/src/common/app_spaces.dart';
import 'package:finance_app/src/common/config.dart';
import 'package:finance_app/src/entities/journal_account_amount.dart';
import 'package:finance_app/src/entities/ocr_attachment_entity.dart';
import 'package:finance_app/src/provider/all_reports/journal/new_journal_entry_provider.dart';
import 'package:finance_app/src/router_gen/router_meta.dart';
import 'package:finance_app/src/utils/cash_utils.dart';
import 'package:finance_app/src/utils/date_time_utils.dart';
import 'package:finance_app/src/widgets/button/normal_popup_button.dart';
import 'package:finance_app/src/widgets/button/normal_text_button.dart';
import 'package:finance_app/src/widgets/common/normal_error_text.dart';
import 'package:finance_app/src/widgets/common_app_bar.dart';
import 'package:finance_app/src/widgets/form/add_form.dart';
import 'package:finance_app/src/widgets/form/attach_file_form.dart';
import 'package:finance_app/src/widgets/form/form_edit_status_inherited_widget.dart';
import 'package:finance_app/src/widgets/form/group_title_form.dart';
import 'package:finance_app/src/widgets/form/price_form.dart';
import 'package:finance_app/src/widgets/form/text_area_input_form.dart';
import 'package:finance_app/src/widgets/form/value_select_form.dart';
import 'package:finance_app/src/widgets/input/form_input_field.dart';
import 'package:finance_app/src/widgets/list_item/journal_account_item.dart';
import 'package:finance_app/src/widgets/wrapper/normal_form_wrapper.dart';
import 'package:flutter/material.dart';
import 'package:tuple/tuple.dart';

@RouterMeta(paramName: "newJournalEntryPage")
class NewJournalEntryPage extends StatefulWidget {
  final int id;
  final String title;

  const NewJournalEntryPage({Key key, this.id, this.title}) : super(key: key);

  @override
  _NewJournalEntryPageState createState() => _NewJournalEntryPageState();
}

class _NewJournalEntryPageState extends State<NewJournalEntryPage>
    with PagePresenter<NewJournalEntryPage, NewJournalEntryProvider> {
  String get title => provider.id == null
      ? S.current.general_journal
      : provider.isEdit == true
          ? S.current.edit_general_journal
          : S.current.general_journal;

  Widget get rightButton => listBuilder<bool>(
        selector: (_, __) => __.isEdit,
        builder: (BuildContext context, bool value, Widget child) =>
            provider.id != null && provider.isEdit == false
                ? _buildPopButton()
                : _buildSaveBtn(),
      );

  @override
  PreferredSizeWidget get appBar => getDefaultAppBar(
          titleWidget: listBuilder<Tuple2<bool, String>>(
            selector: (_, __) =>
                Tuple2<bool, String>(__.isEdit, __.data?.refNumber),
            builder: (BuildContext context, Tuple2<bool, String> value,
                    Widget child) =>
                Text(value.item2 != null ? value.item2 : title),
          ),
          actions: [
            rightButton,
          ]);

  Widget _buildPopButton() => listBuilder<List<String>>(
        selector: (_, __) => List.from(__.menuList),
        builder: (BuildContext context, List<String> value, Widget child) =>
            value.length == 0
                ? Container()
                : NormalMorePopupButton(
                    onSelect: provider.onSelectMenu,
                    menuList: provider.menuList,
                  ),
      );

  Widget _buildSaveBtn() {
    return listBuilder<bool>(
      selector: (_, __) => pageStatus != PageStatus.loading,
      builder: (BuildContext context, bool value, Widget child) => value == true
          ? NormalSaveTextButton(
              onTap: provider.onSave,
            )
          : Container(),
    );
  }

  @override
  Widget wrapperBody(Widget child) {
    return listBuilder<bool>(
        selector: (_, __) => __.isEdit == true || provider.id == null,
        builder: (BuildContext context, bool value, Widget child) =>
            FormEditStatusInheritedWidget(
              isEdit: value,
              child: child,
            ),
        child: child);
  }

  @override
  void initState() {
    provider.currency = Config.defaultCurrency;
    provider.init(widget.id);
    super.initState();
  }

  @override
  Widget get buildWidget => ColoredBox(
        color: Colors.white,
        child: ListView(
          children: [
            listBuilder<bool>(
              selector: (_, __) => __.numberHasError,
              builder: (BuildContext context, bool value, Widget child) =>
                  FromInputField(
                controller: provider.journalNumberController,
                focusNode: provider.journalFocusNode,
                tip: S.current.general_journal_number,
                hasError: value,
              ),
            ),
            listBuilder<String>(
              selector: (_, __) => DateTimeUtils.formatGlobalDateTime(__.date),
              builder: (BuildContext context, String value, Widget child) =>
                  ValueSelectForm(
                title: S.current.date,
                value: value,
                onTap: provider.onChangeDate,
              ),
            ),
            listBuilder<String>(
              selector: (_, __) => __.currency?.name,
              builder: (BuildContext context, String value, Widget child) =>
                  ValueSelectForm(
                title: S.current.currency,
                value: value,
                onTap: provider.onChangeCurrency,
                border: null,
              ),
            ),
            AppSpaces.grayH6,
            GroupTitleForm(
              title: S.current.debit_account,
              title2: S.current.amount,
            ),
            listBuilder<List<JournalAccountAmount>>(
              selector: (_, __) => List.from(__.debitList),
              builder: (BuildContext context, List<JournalAccountAmount> value,
                      Widget child) =>
                  value.length == 0
                      ? ValueSelectForm(
                          title: S.current.debit_account__amount,
                          onTap: provider.onAddDebitAccount,
                        )
                      : Column(
                          children: List.generate(
                              value.length, _buildDebitAccountList),
                        ),
            ),
            AddForm(
              title: S.current.add_debit_account,
              onTap: provider.onAddDebitAccount,
            ),
            AppSpaces.grayH6,
            GroupTitleForm(
              title: S.current.credit_account,
              title2: S.current.amount,
            ),
            listBuilder<List<JournalAccountAmount>>(
              selector: (_, __) => List.from(__.creditList),
              builder: (BuildContext context, List<JournalAccountAmount> value,
                      Widget child) =>
                  value.length == 0
                      ? ValueSelectForm(
                          title: S.current.credit_account__amount,
                          onTap: provider.onAddCreditAccount,
                        )
                      : Column(
                          children: List.generate(
                              value.length, _buildCreditNoteAccountList),
                        ),
            ),
            AddForm(
              title: S.current.add_credit_account,
              onTap: provider.onAddCreditAccount,
            ),
            AppSpaces.grayH6,
            NormalFormWrapper(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.end,
                children: [
                  listBuilder<double>(
                    selector: (_, __) => __.debitAmount,
                    builder:
                        (BuildContext context, double value, Widget child) =>
                            _buildDebitTotal(),
                  ),
                  AppSpaces.h30,
                  listBuilder<double>(
                    selector: (_, __) => __.creditAmount,
                    builder:
                        (BuildContext context, double value, Widget child) =>
                            _buildCreditTotal(),
                  ),
                  FormStatusWidget(
                    enable: Column(
                      crossAxisAlignment: CrossAxisAlignment.end,
                      children: [
                        AppSpaces.h30,
                        _buildUnbalancedTotal(),
                        listBuilder<bool>(
                          selector: (_, __) => __.showMustEqual,
                          builder: (BuildContext context, bool value,
                                  Widget child) =>
                              NormalErrorText(
                            isVisibility: value,
                            content: S.current.debit__credit_must_be_equal,
                          ),
                        ),
                      ],
                    ),
                    disable: Container(),
                  ),
                ],
              ),
            ),
            listBuilder<bool>(
              selector: (_, __) => __.isEdit || __.id == null,
              builder: (BuildContext context, bool value, Widget child) =>
                  !value ? AppSpaces.grayH6 : Container(),
            ),
            TextAreaInputForm(
              title: S.current.memo,
              controller: provider.memoController,
              focusNode: provider.memoFocusNode,
              error: S.current.this_field_is_compulsory,
              isVisibleError: false,
            ),
            NormalFormWrapper(
              child:
                  listBuilder<Tuple2<List<String>, List<OcrAttachmentEntity>>>(
                selector: (_, __) => Tuple2(
                    List.from(__.files), List.from(__.attachments ?? [])),
                builder: (BuildContext context,
                        Tuple2<List<String>, List<OcrAttachmentEntity>> value,
                        Widget child) =>
                    AttachFileForm(
                  onAdd: provider.onAddAttachment,
                  files: value.item1,
                  onSelectFile: provider.onSelectFile,
                  attachments: value.item2,
                  onSelectAttachment: provider.onSelectAttachment,
                ),
              ),
            ),
            AppSpaces.h30,
          ],
        ),
      );

  Widget _buildDebitTotal() {
    return listBuilder<double>(
      selector: (_, __) => __.debitAmount,
      builder: (BuildContext context, double value, Widget child) => PriceForm(
        title: S.current.debit_amount,
        amount: CashUtils.formatCashAmount(value),
      ),
    );
  }

  Widget _buildCreditTotal() {
    return listBuilder<double>(
      selector: (_, __) => __.creditAmount,
      builder: (BuildContext context, double value, Widget child) => PriceForm(
        title: S.current.credit_amount,
        amount: CashUtils.formatCashAmount(value),
      ),
    );
  }

  Widget _buildUnbalancedTotal() {
    return listBuilder<double>(
      selector: (_, __) => __.unbalancedAmount,
      builder: (BuildContext context, double value, Widget child) => PriceForm(
        title: S.current.unbalanced_amount,
        amount: CashUtils.formatCashAmount(value),
      ),
    );
  }

  Widget _buildDebitAccountList(int index) {
    return listBuilder<JournalAccountAmount>(
      selector: (_, __) => __.debitList[index],
      builder:
          (BuildContext context, JournalAccountAmount value, Widget child) =>
              PressedOpacityButton(
        onPressed: () => FormEditStatusInheritedWidget.ofEnable(context)
            ? provider.onSelectDebit(value)
            : () {},
        child: JournalAccountItem(
          // showHeader: index == 0,
          title: S.current.debit_account,
          amount: CashUtils.formatCashAmount(value.total),
          account: value.account,
        ),
      ),
    );
  }

  Widget _buildCreditNoteAccountList(int index) {
    return listBuilder<JournalAccountAmount>(
      selector: (_, __) => __.creditList[index],
      builder:
          (BuildContext context, JournalAccountAmount value, Widget child) =>
              PressedOpacityButton(
        onPressed: () => FormEditStatusInheritedWidget.ofEnable(context)
            ? provider.onSelectCredit(value)
            : () {},
        child: JournalAccountItem(
          // showHeader: index == 0,
          title: S.current.credit_account,
          amount: CashUtils.formatCashAmount(value.total),
          account: value.account,
        ),
      ),
    );
  }
}
